/**
 * \file  Random.cpp
 * \brief random generator
 */


#if !xOPTION_HEADER_ONLY
    #include "Random.h"
#endif

#include <xLib/Core/Functions.h>
#include <xLib/Core/Utils.h>
#include <xLib/Test/Test.h>
#include <xLib/Debug/Debug.h>
#include <xLib/Debug/NativeError.h>
#include <xLib/Debug/StdError.h>
#include <xLib/Debug/ErrorReport.h>
#include <xLib/Debug/Debugger.h>
#include <xLib/Debug/StackTrace.h>
#include <xLib/Log/Trace.h>

#if   xENV_WIN
    #include "Platform/Win/Random_win.inl"
#elif xENV_UNIX
    #if   xENV_LINUX
        #include "Platform/Unix/Random_unix.inl"
    #elif xENV_BSD
        #include "Platform/Unix/Random_unix.inl"
    #elif xENV_APPLE
        #include "Platform/Unix/Random_unix.inl"
    #endif
#endif


xNAMESPACE_BEGIN2(xlib, crypt)

/**************************************************************************************************
*    IxSeedPolicy
*
**************************************************************************************************/

//-------------------------------------------------------------------------------------------------
inline
IxSeedPolicy::IxSeedPolicy() :
    _seed(0U)
{
    _seed = _seedTimeBased();
}
//-------------------------------------------------------------------------------------------------
inline uint_t
IxSeedPolicy::_seedTimeBased() const
{
    timeval tv = {0, 0};
    int_t iRv = ::gettimeofday(&tv, xPTR_NULL);
    xTEST_DIFF(iRv, - 1);

    return static_cast<uint_t>( tv.tv_usec );
}
//-------------------------------------------------------------------------------------------------
/* static */
inline long_t
IxSeedPolicy::valueMax()
{
   /**
    * FAQ: RAND_MAX
    *
    * Maximum possible value generated by std::rand (int)
    * This value is library-dependent, but is guaranteed to be at least 32767 on any standard
    * library implementation
    */

    return static_cast<int>( RAND_MAX );
}
//-------------------------------------------------------------------------------------------------


/**************************************************************************************************
*    StdSeedPolicy
*
**************************************************************************************************/

//-------------------------------------------------------------------------------------------------
inline
StdSeedPolicy::StdSeedPolicy() :
    IxSeedPolicy()
{
    _construct_impl();
}
//-------------------------------------------------------------------------------------------------
/* virtual */
inline
StdSeedPolicy::~StdSeedPolicy()
{
}
//-------------------------------------------------------------------------------------------------
/* virtual */
inline long_t
StdSeedPolicy::next()
{
    return _next_impl();
}
//-------------------------------------------------------------------------------------------------


/**************************************************************************************************
*    NativeSeedPolicy
*
**************************************************************************************************/

//-------------------------------------------------------------------------------------------------
inline
NativeSeedPolicy::NativeSeedPolicy() :
    IxSeedPolicy()
{
    _construct_impl();
}
//-------------------------------------------------------------------------------------------------
/* virtual */
inline
NativeSeedPolicy::~NativeSeedPolicy()
{
    _destruct_impl();
}
//-------------------------------------------------------------------------------------------------
/* virtual */
inline long_t
NativeSeedPolicy::next()
{
    return _next_impl();
}
//-------------------------------------------------------------------------------------------------

xNAMESPACE_END2(xlib, crypt)
